package com.mdp.oauth2.server.integration.authenticator;

import com.mdp.core.utils.Const;
import com.mdp.core.utils.ObjectTools;
import com.mdp.oauth2.server.integration.IntegrationParams;
import com.mdp.oauth2.server.service.SysUserService;
import com.mdp.oauth2.server.service.UserBaseInfoQueryService;
import com.mdp.qx.DataLvl;
import com.mdp.safe.client.dict.AuthType;
import com.mdp.safe.client.dict.UserType;
import com.mdp.safe.client.entity.DeptPostRole;
import com.mdp.safe.client.entity.Role;
import com.mdp.safe.client.entity.SafeAuthority;
import com.mdp.safe.client.entity.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * 默认登录处理,密码方式
 * 格式 url: http://${domain}/api/m1/oauth2/oauth/token?grant_type=password&username=${username}&password=${前端密码MD5加密后的密码}&scope=all
 * @author chenyc
 * @date 2021-01-12
 **/
public class AuthenticatorAdapter implements IntegrationAuthenticator{

    @Autowired
    UserBaseInfoQueryService userBaseInfoQueryService;

    @Autowired
    SysUserService sysUserService;

    @Autowired
    public PasswordEncoder passwordEncoder;


    Logger logger= LoggerFactory.getLogger(AuthenticatorAdapter.class);


    @Override
    public User authenticate(IntegrationParams integrationParams) {
        User user= loadUserByUserid(integrationParams.getUserloginid(),integrationParams);
        return user;
    }

    /**
     * 查找用户基础信息
     * @param userid 前台登陆编号
     * @return
     */
    public User loadUserByUserid(String userid,IntegrationParams integrationParams){
       User user= userBaseInfoQueryService.getUserByUserid(userid,null);
        //todo: 为了测试方便，将密码设置为与前端上送的密码一致
        user.setPassword(passwordEncoder.encode(integrationParams.getAuthParameter("password")));
        return user;
    }

    @Override
    public void prepare(IntegrationParams integrationParams) {

    }

    @Override
    public boolean supportAuthType(IntegrationParams integrationParams) {
        return AuthType.password.name().equals(integrationParams.getAuthType());
    }

    @Override
    public void complete(IntegrationParams integrationParams) {

    }

    @Override
    public Collection<? extends GrantedAuthority> loadAuthorities(User user, IntegrationParams integrationParams) {
        if(user==null){
            Set<SafeAuthority> safeAuthorities=new HashSet<>();
            SafeAuthority safeAuthority=new SafeAuthority("guest","游客",DataLvl.myDept.getLvl());
            safeAuthorities.add(safeAuthority);
            return   safeAuthorities;
        }
        Collection<? extends GrantedAuthority> authorities=new HashSet<>();
        if(UserType.cust.name().equals(integrationParams.getUserType())){
            authorities=this.loadAuthoritiesForCust(user, integrationParams);
        }else{
            authorities=this.loadAuthoritiesForStaff(user, integrationParams);
        }
        return authorities;
    }


    public Collection<? extends GrantedAuthority> loadAuthoritiesForCust(User user, IntegrationParams integrationParams) {
        List<DeptPostRole> deptPostRoles=loadUserRolesByUserid(user.getUserid(),integrationParams);
        return calcAuthority(user,UserType.cust,integrationParams,deptPostRoles);
    }

    public Collection<? extends GrantedAuthority> loadAuthoritiesForStaff(User user, IntegrationParams integrationParams) {
        List<DeptPostRole> deptPostRoles=loadUserRolesByUserid(user.getUserid(),integrationParams);
        return calcAuthority(user,UserType.staff,integrationParams,deptPostRoles);
    }

    private Collection<? extends GrantedAuthority> calcAuthority(User user,UserType userType, IntegrationParams integrationParams, List<DeptPostRole> deptPostRoles) {
        Set<SafeAuthority> safeAuthorities=new HashSet<>();
        Set<String> deptids=new HashSet<>();
        Set<String> branchIds=new HashSet<>();
        Map<String,DeptPostRole> deptPostRoleMap=new HashMap<>();
        Map<String,DeptPostRole> masterMap=new HashMap<>();
        DataLvl maxDataLvl=DataLvl.noDef;
        DeptPostRole maxDataLvlDeptPostRole=null;
        Set<String> roleidSet=new HashSet();
        if(deptPostRoles !=null && deptPostRoles.size()>0){
            for (DeptPostRole deptPostRole : deptPostRoles) {

                deptids.add(deptPostRole.getDeptid());
                branchIds.add(deptPostRole.getBranchId());
                if(deptPostRole.getDataLvl()==null){
                    deptPostRole.setDataLvl(DataLvl.noDef.getLvl());
                }
                deptPostRoleMap.put(deptPostRole.getRoleid(),deptPostRole);
                if("1".equals(deptPostRole.getMaster())){
                    masterMap.put(deptPostRole.getRoleid(),deptPostRole);
                }
                DataLvl dataLvl=DataLvl.getDataLvl(deptPostRole.getDataLvl());
                if(maxDataLvl.compareToLvl(dataLvl)<0){
                    maxDataLvl=dataLvl;
                    maxDataLvlDeptPostRole=deptPostRole;
                }
            }
        }
        String roleids= (String) user.get("roleids");
        if(StringUtils.hasText(roleids)){
            String[] roleidss= roleids.split(",");
            for (String roleid : roleidss) {
                roleidSet.add(roleid);
            }
        }
        if(Const.superAdminRole.equals(user.getDisplayUserid())||Const.superAdminRole.equals(user.getUserid())){
            roleidSet.add(Const.superAdminRole);
        }
        if(user.getDisplayUserid().equals(user.getBranchId())||user.getUserid().equals(user.getBranchId())){
            roleidSet.add("branchAdmin");
        }
        if("1".equals(user.getMemType())) {
            roleidSet.add("branchAdmin");
        }

        roleidSet.add(userType.name());
        roleidSet.add("user");//只要登录就有权限的角色


        for (String roleid : roleidSet) {
            if(deptPostRoleMap.containsKey(roleid)){
                continue;
            }
            Role role=sysUserService.getRole(roleid);
            if(role==null){
                continue;
            }
            DataLvl dataLvl=DataLvl.getDataLvl(role.getDataLvl());
            maxDataLvl=dataLvl.compareTo(maxDataLvl)>0?dataLvl:maxDataLvl;
            SafeAuthority safeAuthority=new SafeAuthority(role.getRoleid(),role.getRolename(),role.getDataLvl());
            safeAuthorities.add(safeAuthority);
        }
        if(!deptids.isEmpty()){
            user.setDeptids(deptids);
        }
        if (!branchIds.isEmpty()) {
            user.setBranchIds(branchIds);
        }
        for (DeptPostRole deptPostRole : deptPostRoleMap.values()) {
            SafeAuthority safeAuthority=new SafeAuthority(deptPostRole.getRoleid(),deptPostRole.getRolename(),deptPostRole.getDataLvl());
            safeAuthorities.add(safeAuthority);
        }
        user.setMaxDataLvl(maxDataLvl.getLvl());

        DataLvl maxDataLvl2=null;
        DeptPostRole maxDataLvlDeptPostRole2=null;
        if( !masterMap.isEmpty() ){
            maxDataLvl2=DataLvl.myDept;
            if(masterMap.size()>1){
                //找出等级高的
                for (DeptPostRole deptPostRole : masterMap.values()) {
                    DataLvl dataLvl=DataLvl.getDataLvl(deptPostRole.getDataLvl());
                    if(maxDataLvl2.compareToLvl(dataLvl)<0){
                        maxDataLvl2=dataLvl;
                        maxDataLvlDeptPostRole2=deptPostRole;
                    }
                }

            }else {
                maxDataLvlDeptPostRole2=masterMap.values().stream().findFirst().get();
            }
        }else {
            maxDataLvlDeptPostRole2=maxDataLvlDeptPostRole;
        }
        if(maxDataLvlDeptPostRole2==null){
            maxDataLvlDeptPostRole2=maxDataLvlDeptPostRole;
        }
        if(maxDataLvlDeptPostRole2!=null && ObjectTools.isNotEmpty( maxDataLvlDeptPostRole2.getBranchId()) && maxDataLvlDeptPostRole2.getBranchId().equals(user.getBranchId())){
            user.setDeptid(maxDataLvlDeptPostRole2.getDeptid());
            user.setDeptName(maxDataLvlDeptPostRole2.getDeptName());
            user.setBranchId(maxDataLvlDeptPostRole2.getBranchId());
            user.setBranchName(maxDataLvlDeptPostRole2.getBranchName());
        }

        setShopInfoToUser(user);
        return safeAuthorities;
    }
    /**
     * 查找用户的角色列表
     */
    public List<DeptPostRole> loadUserRolesByUserid(String userid,IntegrationParams integrationParams){
        Map<String,Object> extParams=new HashMap<>();
        String deptid= (String) integrationParams.getAuthParameter("deptid");
        if(StringUtils.hasText(deptid)){
            extParams.put("deptid",deptid);
        }
        return userBaseInfoQueryService.getUserDeptPostRoles(userid,extParams);
    }

    /**
     * 设置用户归属商户
     * @param user
     */
    private void setShopInfoToUser(User user) {
        try {
//                PlatformVo platformVo=platClientService.getPlatformVo();
//                user.setShopId(platformVo.getShopId());
//                user.setShopName(platformVo.getPlatformTitle());
        }catch (Exception e){
            logger.error("",e);
        }


    }

    public static void main(String[] args) {
        DataLvl dept=DataLvl.myDept;
        DataLvl max=DataLvl.allowAll;

        System.out.println("dept.comaprtToLvl:" + dept.compareToLvl(max));
        if(dept.compareToLvl(max)>0){
            System.out.println("dept>max");
        }else{

            System.out.println("dept<=max");
        }
    }
}
